package top.healthylife.gateway.platform.youshu.api.utils;

import cn.hutool.http.HttpUtil;
import com.alibaba.fastjson.JSONObject;
import lombok.SneakyThrows;
import lombok.extern.slf4j.Slf4j;
import top.healthylife.basics.utils.exception.BusinessException;
import top.healthylife.basics.utils.utils.SystemThreadLocal;
import top.healthylife.gateway.core.util.SystemConfigUtils;
import top.healthylife.gateway.dto.request.req.ApiReqDto;
import top.healthylife.gateway.platform.youshu.api.config.SystemConfig;
import top.heathylife.gateway.common.cons.SystemCons;
import top.heathylife.gateway.common.po.RecordRequestInfo;

import java.util.HashMap;
import java.util.Map;


/**
 * @author Gaozexi
 * @version 1.0
 * @date 2020/4/30 10:43
 */
@Slf4j
public class YoushuHttpUtil {

    private static final String SUCCESS = "0000";
    private static final String NO_DATA = "0001";
    private static final String CODE = "code";
    private static final String MSG = "msg";
    private static final String PRO_URL = "http://open.yscredit.com/api/request";
    private static final String SIT_URL = "http://open-test.yscredit.com/api/request";
    private static final String SIT = "SIT";
    private static final String PRO = "PRO";
    private static final Map<String, String> RESPONSE_MAP = new HashMap<>();


    static {
        RESPONSE_MAP.put("0000", "查询成功");
        RESPONSE_MAP.put("0001", "查询无记录");
        RESPONSE_MAP.put("0002", "查询失败");
        RESPONSE_MAP.put("1000", "账号不存在或被禁用");
        RESPONSE_MAP.put("1001", "请求的接口不存在");
        RESPONSE_MAP.put("1002", "没有该接口的访问权限");
        RESPONSE_MAP.put("1003", "args 参数 json 格式错误");
        RESPONSE_MAP.put("1004", "传入参数为空或格式错误");
        RESPONSE_MAP.put("1005", "数据签名错误");
        RESPONSE_MAP.put("1007", "超出请求并发限制");
        RESPONSE_MAP.put("1010", "余额不够，无法进行查询");
        RESPONSE_MAP.put("1011", "查询权限已被限制");
        RESPONSE_MAP.put("1099", "非法 IP 请求");
        RESPONSE_MAP.put("9999", "系统异常");
    }


    @SneakyThrows
    public static <T> T httpRequest(ApiReqDto dto, String apiCode, Class<T> cls) {
        log.info("收到请求参数为:{}", JSONObject.toJSONString(dto));
        //1.获取账号信息
        SystemConfig systemConfig = getSystemConfigInfo();
        log.info("当前账号参数信息:{}", JSONObject.toJSONString(dto));
        //2.获取接口请求地址
        String apiUrl = getApiUrlByEnv(systemConfig);
        //3.参数加密
        String priateKey = systemConfig.getPriateKey();
        EncryptDto encryptDto = new EncryptDto(systemConfig.getUid(), apiCode, JSONObject.toJSONString(dto));
        encryptDto.signature(priateKey);
        String params = encryptDto.toString();
        String finalUrl = apiUrl + "?" + params;
        log.info("最终访问的url地址:{}",finalUrl);
        RecordRequestInfo.recordRequest(finalUrl, null, null, "get");
        String body = HttpUtil.createGet(finalUrl).execute().body();
        //将三方元数据存储到线程变量
        SystemThreadLocal.set(SystemCons.ORIGIN_DATA,body);
        log.info("有数接口返回:{}",body);
        JSONObject jsonObject = JSONObject.parseObject(body);
        if (!jsonObject.containsKey(CODE)) {
            throw new BusinessException("有数数据结构响应异常");
        }
        String code = jsonObject.getString(CODE);
        String msg = jsonObject.getString(MSG);
        if (code.equals(SUCCESS)) {
            return jsonObject.toJavaObject(cls);
        }
        if(code.equals(NO_DATA)){
            return jsonObject.toJavaObject(cls);
        }
        if (RESPONSE_MAP.containsKey(code)) {
            throw new BusinessException("有数数据响应:{}", RESPONSE_MAP.get(code));
        }
        throw new BusinessException("有数数据响应:{}", msg);

    }

    private static SystemConfig getSystemConfigInfo() {
        //获取配置信息
        return (SystemConfig) SystemConfigUtils.get();
    }

    private static String getApiUrlByEnv(SystemConfig systemConfig) {
        String env = systemConfig.getEnv();
        if (SIT.equalsIgnoreCase(env)) {
            return SIT_URL;
        } else if (PRO.equalsIgnoreCase(env)) {
            return PRO_URL;
        } else {
            throw new BusinessException("获取环境信息错误,期望在[SIT,PRO],实际是{}", env);
        }
    }


}
